package org.gdstash.ui.table;

import javax.swing.*;
import javax.swing.table.TableRowSorter;
import java.util.Comparator;

public class GDItemCollectionSorter extends TableRowSorter<GDItemCollectionTableModel> {
    private static final int SORTORDER_DEFAULT = 0;
    private static final int SORTORDER_BASE = 1;
    private static final int SORTORDER_BASE_REV = 2;
    private static final int SORTORDER_NAME = 3;
    private static final int SORTORDER_NAME_REV = 4;
    private static final int SORTORDER_LEVEL = 5;
    private static final int SORTORDER_LEVEL_REV = 6;
    private static final int SORTORDER_SC = 7;
    private static final int SORTORDER_SC_REV = 8;
    private static final int SORTORDER_HC = 9;
    private static final int SORTORDER_HC_REV = 10;
    private static final Comparator<GDItemCollectionRow> COMP_BASE;
    private static final Comparator<GDItemCollectionRow> COMP_BASE_REV;
    private static final Comparator<GDItemCollectionRow> COMP_NAME;
    private static final Comparator<GDItemCollectionRow> COMP_NAME_REV;
    private static final Comparator<GDItemCollectionRow> COMP_LEVEL;
    private static final Comparator<GDItemCollectionRow> COMP_LEVEL_REV;
    private static final Comparator<GDItemCollectionRow> COMP_SC;
    private static final Comparator<GDItemCollectionRow> COMP_SC_REV;
    private static final Comparator<GDItemCollectionRow> COMP_HC;
    private static final Comparator<GDItemCollectionRow> COMP_HC_REV;
    private int sortOrder;

    public GDItemCollectionSorter() {
        this(null);
    }

    public GDItemCollectionSorter(final GDItemCollectionTableModel model) {
        this.setModel(model);
    }

    @Override
    public void setModel(final GDItemCollectionTableModel m) {
        super.setModel(m);
        if (m != null) {
            this.setSortable(0, false);
            this.sortOrder = 0;
        }
    }

    @Override
    public void toggleSortOrder(final int column) {
        if (column == 0) {
            if (this.sortOrder == 1) {
                this.sortOrder = 2;
            } else {
                this.sortOrder = 1;
            }
        }
        if (column == 1) {
            if (this.sortOrder == 3) {
                this.sortOrder = 4;
            } else {
                this.sortOrder = 3;
            }
        }
        if (column == 2) {
            if (this.sortOrder == 5) {
                this.sortOrder = 6;
            } else {
                this.sortOrder = 5;
            }
        }
        if (column == 3) {
            if (this.sortOrder == 7) {
                this.sortOrder = 8;
            } else {
                this.sortOrder = 7;
            }
        }
        if (column == 4) {
            if (this.sortOrder == 9) {
                this.sortOrder = 10;
            } else {
                this.sortOrder = 9;
            }
        }
    }

    static {
        COMP_BASE = new BaseComparator();
        COMP_BASE_REV = new BaseReverseComparator();
        COMP_NAME = new NameComparator();
        COMP_NAME_REV = new NameReverseComparator();
        COMP_LEVEL = new LevelComparator();
        COMP_LEVEL_REV = new LevelReverseComparator();
        COMP_SC = new SoftcoreComparator();
        COMP_SC_REV = new SoftcoreReverseComparator();
        COMP_HC = new HardcoreComparator();
        COMP_HC_REV = new HardcoreReverseComparator();
    }

    @Override
    public void sort() {
        final GDItemCollectionTableModel model = this.getModel();
        if (this.sortOrder == 1) {
            model.sort(GDItemCollectionSorter.COMP_BASE);
        }
        if (this.sortOrder == 2) {
            model.sort(GDItemCollectionSorter.COMP_BASE_REV);
        }
        if (this.sortOrder == 3) {
            model.sort(GDItemCollectionSorter.COMP_NAME);
        }
        if (this.sortOrder == 4) {
            model.sort(GDItemCollectionSorter.COMP_NAME_REV);
        }
        if (this.sortOrder == 5) {
            model.sort(GDItemCollectionSorter.COMP_LEVEL);
        }
        if (this.sortOrder == 6) {
            model.sort(GDItemCollectionSorter.COMP_LEVEL_REV);
        }
        if (this.sortOrder == 7) {
            model.sort(GDItemCollectionSorter.COMP_SC);
        }
        if (this.sortOrder == 8) {
            model.sort(GDItemCollectionSorter.COMP_SC_REV);
        }
        if (this.sortOrder == 9) {
            model.sort(GDItemCollectionSorter.COMP_HC);
        }
        if (this.sortOrder == 10) {
            model.sort(GDItemCollectionSorter.COMP_HC_REV);
        }
    }

    public static class BaseComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            return 0;
        }
    }

    private static class BaseReverseComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return -iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            return 0;
        }
    }

    public static class NameComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            return ir1.level.text.compareTo(ir2.level.text);
        }
    }

    private static class NameReverseComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return -iName;
            }
            return ir1.level.text.compareTo(ir2.level.text);
        }
    }

    private static class LevelComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            return ir1.name.text.compareTo(ir2.name.text);
        }
    }

    private static class LevelReverseComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return -iLevel;
            }
            return ir1.name.text.compareTo(ir2.name.text);
        }
    }

    private static class SoftcoreComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            int iFound = 0;
            if (ir1.softcore != ir2.softcore) {
                if (ir1.softcore) {
                    iFound = -1;
                } else {
                    iFound = 1;
                }
            }
            if (iFound != 0) {
                return iFound;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            return 0;
        }
    }

    private static class SoftcoreReverseComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            int iFound = 0;
            if (ir1.softcore != ir2.softcore) {
                if (ir1.softcore) {
                    iFound = -1;
                } else {
                    iFound = 1;
                }
            }
            if (iFound != 0) {
                return -iFound;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            return 0;
        }
    }

    private static class HardcoreComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            int iFound = 0;
            if (ir1.hardcore != ir2.hardcore) {
                if (ir1.hardcore) {
                    iFound = -1;
                } else {
                    iFound = 1;
                }
            }
            if (iFound != 0) {
                return iFound;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            return 0;
        }
    }

    private static class HardcoreReverseComparator implements Comparator<GDItemCollectionRow> {
        @Override
        public int compare(final GDItemCollectionRow ir1, final GDItemCollectionRow ir2) {
            int iFound = 0;
            if (ir1.hardcore != ir2.hardcore) {
                if (ir1.hardcore) {
                    iFound = -1;
                } else {
                    iFound = 1;
                }
            }
            if (iFound != 0) {
                return -iFound;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            return 0;
        }
    }
}
